Built with R version 4.4.0.

1 Introduction

The purpose of this document is to make open and share-able the research methods used for my dissertation on nearshore fish communities in Alaska working towards a PhD in marine biology at the University of Alaska Fairbanks. Here, I cover steps of the data preparation for my second and third chapters concerning spatial and temporal distributions of nearshore fishes across the state. This and other files can be accessed via the Kachemak Bay National Estuarine Research Reserve’s github nearshore fish repository.

In this document I share exploratory data analyses conducted on the NOAA Nearshore Fish Atlas (NFA) database. The NFA database can be found here, https://alaskafisheries.noaa.gov/mapping/sz/. Namely, this document contains the steps taken after cleaning/wrangling raw data. In particular I produce various visualizations of the data in space and time. Initial wrangle steps can be viewed at this Rpubs page and its data objects are sourced below (file “NFA.rda”).

1.1 Set up

Load required packages, define directory, set options, source/load files:

# Packages
library(tidyverse)
library(lubridate)
library(here)
library(leaflet)
library(RColorBrewer)

# Directory
wd = here()
dirs = wd %>% list.files() %>% str_subset(pattern = "^README|^LICENSE|.md$|.Rproj$", negate = TRUE)
for (i in seq_along(dirs)) {
  name = str_replace_all(dirs[i], "^", "dir.")
  path = str_replace_all(dirs[i], "^", str_c(wd, "/"))
  assign(name, path)
  rm(name, path, i)
}

# Options

# Source/Load
load(file.path(dir.data, "NFA_wrangled.rda")) # wrangled data

1.2 Background and objectives

Based on my own research and related literature, I can broadly interpret these beach seine data in a spatiotemporal context. Depending on when (time of year) and where (location and habitat), I have a general structure in mind of the diversity of the community. Depending on who’s there, I have a rough guess of the relative abundance of each community member (at least for the more commonly caught ones). My hope with working with the NFA data is that this broad understanding can be formally tested with inference and statistics, and that more informative research questions can be answered.

Findings from other nearshore fish researchers largely agree that seasonality (or some related environmental condition) is a strong predictor of community or species presence. Interannual differences can exhibit wide variability and should be accounted for whenever possible. And at larger time-scales (e.g., decadal), communities exhibit changes which may relate to regime shifts occurring more broadly than the nearshore.

Spatially, large-scale (regional) effects appear to be as or more important than sub-regional or local-scale effects. However, many studies also find significant relationships in community response at these smaller scales. Likely, the most appropriate spatial consideration depends on the question being asked. So maybe a more appropriate question to ask of the NFA data is if there any significant spatial scales discernible in the data, and also how should we address those scales in future research, such as studies on subsets of the taxa or habitat management considerations.

I’ll start by exploring the structure of our ‘visits’ dataframe, and then I’ll move on to visualizing the information derived from out ‘catch’ dataframe.

2 Exploring visit data

2.1 Summary of visits

Remember that in the data wrangling stage, we created a new sample identifier based on site and date which we called VisitID. Let’s take a look at the variables associated with each VisitID:

glimpse(visits)
## Rows: 1,867
## Columns: 7
## $ VisitID    <chr> "1_2001-07-24", "1_2002-03-25", "1_2001-04-26", "1_2002-07-…
## $ Replicates <int> 5, 7, 4, 4, 5, 3, 4, 2, 6, 1, 2, 2, 6, 4, 4, 4, 4, 3, 2, 2,…
## $ Date       <date> 2001-07-24, 2002-03-25, 2001-04-26, 2002-07-24, 2003-03-22…
## $ Lat        <dbl> 58.56626, 58.56296, 58.56408, 58.56755, 58.55804, 58.56858,…
## $ Lon        <dbl> -134.9105, -134.9082, -134.9137, -134.9133, -134.9102, -134…
## $ MeshSize   <dbl> 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2, 3.2,…
## $ Cluster    <fct> 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 326,…

During the wrangling stage, I decided that Replicates and MeshSize should be the main covariates that needed consideration. At this point they are classed as integers/numbers, but we will probably want them to be factors instead. Cluster is a byproduct of clustering some sites together, so it may not be needed if we’re using Lat/Lon as our primary explanatory variable. Still, it could be a useful grouping factor later on. Date will likely be mutated into multiple additional periods (day of year, month, year) to see if any of those factors are useful in explaining fish data. We’ll address edits to these variables as they come up in our exploration.

2.2 Spatial distribution

leaflet(visits) %>% 
  addTiles(options = tileOptions(minZoom = 3.5,
                                 zIndex = 0.5)) %>%
  setView(lat = 65, lng = -152, zoom = 3.5) %>%
  addSimpleGraticule(interval = 5) %>%  
  addCircleMarkers(lng = ~Lon, lat = ~Lat,
                   stroke = FALSE,
                   popup = ~VisitID,
                   clusterOptions = markerClusterOptions())

In the map above we can view all of our samples from across Alaska. Leaflet options are nice because you can optionally group samples on the map and show a boundary polygon of the area they cover when you hover over their icon. At the minimum zoom level (3.5), we see the largest group spanning nearly all of Southeast Alaska, followed by a group in Southcentral that covers Prince William Sound, Cook Inlet, and the northern half of Kodiak Island. The third largest group forms a much smaller polygon area around Utqiagvik. From there, we see even smaller groups from the Eastern Beaufort Sea around Kaktovik, the Bering Strait and Southern Chukchi Sea near Kotzebue, and Bristol Bay. There are also two groups from the Alaska Peninsula and Aleutian Islands, one focused around Adak and another spanning from Sand Point to Unalaska. We can see how subsets of the samples change by zooming in. When there are single samples in view, hovering over those will tell us its VisitID name.

Obviously, this visualization of the data is not perfect and pretty rough- note that the groups are formed by the overlap of samples based on pixel radius (10). For example, the polygon of samples from Bristol Bay at the minimum zoom level actually crosses the Alaska Peninsula to include a sample from Aghiyuk Island. Although, the map is useful in gaining a general understanding of the existing clusters of samples within the NFA database.

2.3 Regions

We may want to define a spatial factor based on these rough groupings as a starting place to see if the smaller, more isolated groups should be lumped with other groups or not. Actually, the NFA already has a Region classifier per site, but the reason I do not want to use it is because they linked Region to SiteID. When we created our new VisitID, some samples now contained two Region labels- these were mostly cases from around Utqiagvik where some were labelled as Chuckchi and others as Beaufort but actually occurred on the same day and within a very short distance of each other.

Instead of using the the given regional classes, let’s just make our own variable called ‘Region’ and add it to the our visits df:

# Start with events so that we can make use of Location info for unique cases,
regions = events %>%
  select(EventID, VisitID, Lat, Lon, Location) %>%
  mutate(Region = case_when(Lat > 69 & Lat < 80 & Lon > -150 & Lon < -140 ~ "Beaufort East",
                            Lat > 69 & Lat < 80 & Lon > -160 & Lon < -150 ~ "Chukchi/Beaufort",
                            Lat > 65 & Lat < 69 & Lon > -170 & Lon < -160 ~ "Chukchi South",
                            Lat > 57 & Lat < 60 & Lon > -165 & Lon < -155 ~ "Bristol Bay",
                            Lat > 50 & Lat < 55 & Lon > -180 & Lon < -175 ~ "Aleutians Adak",
                            Lat > 50 & Lat < 55 & Lon > -170 & Lon < -165 ~ "Aleutians Unalaska",
                            Lat > 55 & Lat < 65 & Lon > -155 & Lon < -145 ~ "GOA Southcentral",
                            Lat > 53 & Lat < 61 & Lon > -148 & Lon < -130 ~ "GOA Southeast"))

# Check which samples we missed,
filter(regions, is.na(Region))
## # A tibble: 7 × 6
##   EventID VisitID           Lat   Lon Location                            Region
##     <dbl> <chr>           <dbl> <dbl> <chr>                               <chr> 
## 1    6635 1564_2006-06-22  52.7 -171. Yunaska Island                      <NA>  
## 2    6636 1565_2006-07-26  56.2 -157. Semidi Islands, Aghiyuk Island      <NA>  
## 3    6637 1566_2006-07-31  55.1 -160. Shumagin Islands, Bendel Island     <NA>  
## 4    6638 1566_2006-07-31  55.1 -160. Shumagin Islands, Bendel Island     <NA>  
## 5    6639 1568_2006-07-31  55.1 -160. Shumagin Islands, Spectacle Island  <NA>  
## 6    6640 1569_2006-07-31  55.1 -160. Shumagin Islands, Nagai Island, Mi… <NA>  
## 7    6641 1569_2006-07-31  55.1 -160. Shumagin Islands, Nagai Island, Mi… <NA>
# Let's address those using Location,
regions = mutate(regions,
       Region = case_when(!is.na(Region) ~ Region,
                          is.na(Region) & str_detect(Location, "Yunaska") ~ "Aleutians Yunaska",
                          is.na(Region) & str_detect(Location, "Aghiyuk") ~ "Aleutians Aghiyuk",
                          is.na(Region) & str_detect(Location, "Shumagin") ~ "Aleutians Shumagin"))

# Check again (should be 0),
filter(regions, is.na(Region)) %>% nrow()
## [1] 0

Now let’s add Region as a factor to our visits df, and show it on a map. Since we’re manipulating our data objects again, let’s also rename visits so that we can keep track of our changes.

# Call our wrangled df version visits.0 and remove the non-version 'visits' if it's there,
if ("visits" %in% ls()) assign("visits.0", visits)
if ("visits" %in% ls()) rm(visits)

# Make Region a factor and join by VisitID,
visits.1 = regions %>%
  select(VisitID, Region) %>%
  distinct() %>%
  mutate(Region = as.factor(Region)) %>%
  left_join(visits.0, ., by = "VisitID")

# Function for regional palette
palette.region = colorFactor(palette = brewer.pal(n = visits.1$Region %>% n_distinct(),
                                                  name = 'Spectral'),
                             domain = factor(visits.1$Region))

# Map
leaflet(visits.1) %>% 
  addTiles() %>%
  addCircleMarkers(lng = ~Lon, lat = ~Lat,
                   color = ~palette.region(Region),
                   fillColor = ~palette.region(Region),
                   popup = ~paste(Region, VisitID),
                   stroke = FALSE) %>%
  addLegend(position = "topright",
            pal = palette.region, values = ~Region,
            title = "Region",
            opacity = 0.75)

Like we saw before, the majority of our samples are located in the Gulf of Alaska (GOA), namely Southeast (SEAk) and Southcentral (SCAK). If we were to look at differences in catach in the GOA, it’d be cool if we could include the Aleutian samples too. Obviously, we’ll want to address those few instances from Aghiyuk, Shumagin, and Yunaska, and ideally we aggregate them into one or two groups. We also see relatively small sample sizes from Bristol Bay and from East Beaufort, which may or may not be prohibitive in conducting meaningful tests. One other consideration is the couple of samples along the Bering Strait coast which are lumped together with a larger concentration of samples from South Chukchi.

Some of our first analyses should see if the more isolated samples are different from the other samples. If not, then we can aggregate. If yes, then we should report any significant tests.

2.4 Temporal distribution

Next we’ll want to take a look at how our samples distribute throughout various time periods. This will give us a good idea of how well our samples may or may not overlap- particularly, we’ll want to see overlaps in years and months for better comparisons of the catch data.

# First create a df specifically containing at time variables
times = visits.1 %>%
  select(VisitID, Date) %>%
  mutate(Year = year(Date),
         Month = month(Date, label = TRUE),
         Week = week(Date),
         Day = yday(Date))

# Year
times %>%
  count(Year) %>%
  ggplot(., aes(x = Year, y = n)) +
  geom_col() +
  geom_text(aes(label = n), vjust = -0.5, color = "blue") +
  labs(x = NULL, y = NULL, title = "No. samples per Year")

# Year without 1976
times %>%
  filter(Year > 1980) %>%
  count(Year) %>%
  ggplot(., aes(x = Year, y = n)) +
  geom_col() +
  geom_text(aes(label = n), vjust = -0.5, color = "blue") +
  labs(x = NULL, y = NULL, title = "No. samples per Year without 1976")

# Month
times %>%
  count(Month) %>%
  ggplot(., aes(x = Month, y = n)) +
  geom_col() +
  geom_text(aes(label = n), vjust = -0.5, color = "blue") +
  labs(x = NULL, y = NULL, title = "No. samples per Month")

# Week
times %>%
  count(Week) %>%
  ggplot(., aes(x = Week, y = n)) +
  geom_col() +
  geom_text(aes(label = n), hjust = -0.15, angle = 90, color = "blue") +
  labs(x = NULL, y = NULL, title = "No. samples per Week")

# Day of Year
times %>%
  count(Day) %>%
  distinct() %>%
  ggplot(., aes(x = Day, y = n)) +
  geom_col() +
  labs(x = NULL, y = NULL, title = "No. samples per Day of Year")

By year, we see a large variability in number of samples, as well as a lone 1976 year which I recognize to be Blackburn’s dataset from Lower Cook Inlet. That 1976 is an interesting dataset that could be useful for a look at catches over time in that specific area, but it’ll need to be excluded from any other comparisons. The lowest number of samples occur in 2010, 2020, and 2021. We may want to pay close attention to these years in case they show up as outliers. It seems that 1996-2000 is a period of heavy sampling, followed by the mid 2010s and somewhat active year in 2006.

By month, we see an obvious uptick during the summer which makes sense given winter conditions along most of Alaska’s coast (light, ice, etc.). March and October are interesting months because of the potential for impacts on fishes during years with warmer shoulder seasons. November thru February will likely be removed for our purposes. Our key months look to be June, July and August, with possible inclusion of April, May, and September.

It’s interesting if we look at the by-week and by-day graphs, we see a dip in sampling around mid-June/early-July. Not sure why this is- maybe related to more targeting of juvenile salmonids in early June, or maybe so reduced effort around the 4th of July holiday.

2.5 Year & month by region

Let’s now see how our samples overlap by Region and Year, and by Region and Month. For these purposes, let’s combine the Aleutians into one group for now, and remove the 1976 data.

# Samples by Year and Region,
left_join(filter(times, Year > 1980),
          select(visits.1, VisitID, Region), by = "VisitID") %>%
  mutate(Region = case_when(str_detect(Region, "Aleutians") ~ "Aleutians",
                            !str_detect(Region, "Aleutians") ~ Region)) %>%
  ggplot(aes(x = Date, y = Region, color = Region)) +
  geom_boxplot() +
  geom_jitter(size = 0.5, alpha = 0.75) +
  stat_summary(geom = "text", vjust = -1.9, color = "black",
               fun.data = function(x) {
                 return(c(y = median(x), label = length(x)))
               }) +
  scale_color_brewer(palette = "Spectral") +
  scale_x_date(date_labels = "%y",
               date_breaks = "2 years") +
  labs(x = "Year", y = "Region",
       title = "Samples by Year and Region",
       subtitle = "No. samples centered over median") +
  theme_minimal() +
  theme(legend.position = "none")

# Samples by Month and Region,
left_join(filter(times, Year > 1980),
          select(visits.1, VisitID, Region), by = "VisitID") %>%
  mutate(Region = case_when(str_detect(Region, "Aleutians") ~ "Aleutians",
                            !str_detect(Region, "Aleutians") ~ Region)) %>%
  ggplot(aes(x = Month, y = Region, color = Region)) +
  geom_boxplot() +
  geom_jitter(size = 0.5, alpha = 0.75) +
  stat_summary(geom = "text", vjust = -1.9, color = "black",
               fun.data = function(x) {
                 return(c(y = median(x), label = length(x)))
               })+
  scale_color_brewer(palette = "Spectral") +
  labs(x = "Month", y = "Region",
       title = "Samples by Month and Region",
       subtitle = "Excluding 1976; no. samples labelled by month") +
  theme_minimal() +
  theme(legend.position = "none")

Interesting that each region’s samples center on a different year. At a glance, I see the most overlap in 2006 where the Aleutians and both GOA regions look to have similar sample densities, plus there is a smattering of Chukchi/Beaufort sampling too. In 2009, the Bristol Bay samples may be compared with both GoA regions and the Chukchi/Beaufort, although the samples look more sparse across the regions. And in 2013, the Chukchi/Beaufort has good overlap with both GOA regions again. I see nice periods of comparison between SEAK and SCAK, but there is also a concerning difference in yearly distribution of samples between the two regions. Depending on how important year effects appear- we may need to trim the data for better comparisons.

By month, we see that August contains samples from all regions. June is the center for SEAK and the Aleutians, July for SCAK, and August for Chukchi/Beaufort. Best comparisons from this monthly view may be an August (or lumped July + August) comparison of all Regions. Also, a June (or lumped June thru August) comparison of GOA and the Aleutians would be good. And, we should be able to nicely compare SEAK and SCAK from May to September, potentially including April.

For now, we’ll hold off on excluding any of the data. It’ll be better to revisit these considerations after deciding which research questions to tackle, so subsets of the data can be made specific to each one.

2.6 Mesh Size and Replicates

Let’s make similar visuals as before, but now focus on Mesh Size and Replicates in space and time. First, we can re-map the samples to color by Mesh Size and size of points relative Replicates (large dots = more replicates).

# Palette function to color markers
palette.mesh = colorFactor(palette = brewer.pal(n = visits.1$MeshSize %>% n_distinct(),
                                                name = 'Spectral'),
                           domain = factor(visits.1$MeshSize))
# Map
leaflet(visits.1) %>% 
  addTiles() %>%
  addCircleMarkers(lng = ~Lon, lat = ~Lat,
                   radius = ~(sqrt(Replicates*15)),
                   color = ~palette.mesh(MeshSize),
                   fillColor = ~palette.mesh(MeshSize),
                   popup = ~VisitID,
                   stroke = FALSE) %>%
  addLegend(position = "bottomright",
            pal = palette.mesh, values = ~MeshSize,
            title = "Mesh Size (mm)",
            opacity = 0.75)

I have an issue discerning among the seven different sizes since those warmer colors do not diverge well. Although there are some patterns to make note of: the largest mesh size of 12.7 only occurs in a small area of SEAK, the 10 mm samples similarly only occur with the 12.7 mm samples (likely the Lundstrom et al. 2022 gear comparison), and the smallest size at 3 mm only occurs in Cook Inlet. I don’t see any obvious spatial patterns in Replicates, although this may not be the best view of it.

Let’s see the frequency of samples for both variables:

# Table view
table(visits.1$MeshSize)
## 
##    3  3.2    6  6.4  9.5   10 12.7 
##  436  821  286   35   82   59  148
table(visits.1$Replicates)
## 
##   1   2   3   4   5   6   7   8   9  10  12 
## 665 533 334 142  60  90  19  21   1   1   1

There are more 12.7 mm samples than I would have guessed which is a shame because if they are completely different then we lose a lot of samples. I am wondering if sizes are accurate- I would think that 3 mm and 3.2 mm are effectively similar in practice. I am also wondering if some projects report, say 3 mm instead of 3.2 mm, because of rounding. I would assume that the nets used were manufactured in the US, which would mean that specifications are given in standard not metric. Let’s do a quick check on how typical mesh sizes convert from inches to millimeters.

# Function based on inch to millimeter conversion
in_to_mm = function (x) {
  return(y = 25.4 * x)
}

# Typical mesh sizes in inches
sizes = c((1/8), (1/4), (3/8), (1/2), (5/8), (3/4))

# Convert to millimeters
in_to_mm(sizes)
## [1]  3.175  6.350  9.525 12.700 15.875 19.050

There is obviously some funny rounding happening in the data. I do not see an issue by lumping mesh sizes that are within one millimeter. Even if the nets were actually different by fractions of a millimeter, I don’t think it would affect the selectivity of fishes all that much- especially considering that most of these researchers were capturing fish to be measured to the nearest millimeter.

Let’s see that map again with this in mind:

# Palette function for binned sizes
palette.mesh.bin = colorBin(palette = brewer.pal(n = 4, name = 'Spectral'),
                            domain = visits.1$MeshSize %>% unique(),
                            bins =  c(0, 4, 7, 11, 13))
# Map
leaflet(visits.1) %>% 
  addTiles() %>%
  addCircleMarkers(lng = ~Lon, lat = ~Lat,
                   radius = ~(sqrt(Replicates*15)),
                   color = ~palette.mesh.bin(MeshSize),
                   fillColor = ~palette.mesh.bin(MeshSize),
                   popup = ~VisitID,
                   stroke = FALSE) %>%
  addLegend(position = "bottomright",
            colors = c(palette.mesh.bin(3),
                       palette.mesh.bin(6),
                       palette.mesh.bin(9),
                       palette.mesh.bin(12)),
            values = ~MeshSize,
            title = "Mesh Size (mm)",
            opacity = 0.75,
            labels = c("3 or 3.2", "6 or 6.4", "9.5 or 10", "12.7"))

Much easier to read! I see some concerning patterns we’ll want to investigate further as we go. The majority of samples appear to be using the 3.2 mm size, including both Arctic groups that seem to use it exclusively. There is a large density of 6.4 mm samples in Northern SEAK and throughout the Aleutians. The same issues are visible concerning the two larger mesh sizes. We should do a comparison of 3.2 mm and 6.4 mm to see if there are any significant differences in catch.

With the simpler color scheme, I am also noticing the difference in Replicates a little easier. Just looking at GOA and Aleutian samples, I see that many of the 6.4 mm samples are also low-Replicate samples. Although, many of our samples only contain one replicate so this may just be something I’m seeing and not actually a concern.

Let’s take a look at how these variables in graphical format. I’ll go ahead and aggregate similar mesh sizes and re-classify the both variables as factors, and add in variables for year and month.

visits.2 = mutate(visits.1,
                  Replicates = as_factor(Replicates),
                  # Combine similar mesh sizes to the tenth decimal
                  MeshSize = case_when(MeshSize < 4 ~ 3.2,
                                       MeshSize > 4 & MeshSize < 7 ~ 6.4,
                                       MeshSize > 7 & MeshSize < 11 ~ 9.5,
                                       MeshSize == 12.7 ~ 12.7) %>%
                    as.factor()) %>%
  # Add temporal variables
  left_join(select(times, VisitID, Year, Month), by = "VisitID")
# Samples by MeshSize and Year,
filter(visits.2, Year > 1989) %>%
  ggplot(aes(x = Date, y = MeshSize, color = MeshSize)) +
  geom_boxplot() +
  geom_jitter(size = 0.5, alpha = 0.75) +
  stat_summary(geom = "text", vjust = -3, color = "black",
               fun.data = function(x) {
                 return(c(y = median(x), label = length(x)))
               }) +
  scale_color_brewer(palette = "Spectral") +
  scale_x_date(date_labels = "%y",
               date_breaks = "2 years") +
  labs(x = "Year", y = "Mesh Size (mm)",
       title = "Samples by Year and Mesh Size",
       subtitle = "Excluding 1976; no. samples centered over median") +
  theme_minimal() +
  theme(legend.position = "none")

# Samples by Month and MeshSize,
filter(visits.2, Year > 1989) %>%
  ggplot(aes(x = Month, y = MeshSize, color = MeshSize)) +
  geom_boxplot() +
  geom_jitter(size = 0.5, alpha = 0.75) +
  stat_summary(geom = "text", vjust = -3, color = "black",
               fun.data = function(x) {
                 return(c(y = median(x), label = length(x)))
               })+
  scale_color_brewer(palette = "Spectral") +
  labs(x = "Month", y = "Mesh Size (mm)",
       title = "Samples by Month and Mesh Size",
       subtitle = "Excluding 1976; no. samples labelled by month") +
  theme_minimal() +
  theme(legend.position = "none")

# Samples by Replicates and Year,
filter(visits.2, Year > 1989) %>%
  ggplot(aes(x = Date, y = Replicates, color = Replicates)) +
  geom_boxplot() +
  geom_jitter(size = 0.5, alpha = 0.75) +
  stat_summary(geom = "text", vjust = -1, color = "black",
               fun.data = function(x) {
                 return(c(y = median(x), label = length(x)))
               }) +
  scale_color_brewer(palette = "Spectral") +
  scale_x_date(date_labels = "%y",
               date_breaks = "2 years") +
  labs(x = "Year", y = "Replicates",
       title = "Samples by Year and Replicates",
       subtitle = "Excluding 1976; no. samples centered over median") +
  theme_minimal() +
  theme(legend.position = "none")

# Samples by Replicates and Month,
filter(visits.2, Year > 1989) %>%
  ggplot(aes(x = Month, y = Replicates, color = Replicates)) +
  geom_boxplot() +
  geom_jitter(size = 0.5, alpha = 0.75) +
  stat_summary(geom = "text", vjust = -1, color = "black",
               fun.data = function(x) {
                 return(c(y = median(x), label = length(x)))
               })+
  scale_color_brewer(palette = "Spectral") +
  labs(x = "Month", y = "Replicates",
       title = "Samples by Month and Replicates",
       subtitle = "Excluding 1976; no. samples labelled by month") +
  theme_minimal() +
  theme(legend.position = "none")

LS0tCnRpdGxlOiAiTk9BQSBOZWFyc2hvcmUgRmlzaCBBdGxhcywgRXhwbG9yYXRvcnkgRGF0YSBBbmFseXNlcyIKYXV0aG9yOiAiQ2hyaXMgR3VvIgpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IFRSVUUKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICAgIHByaW50OiBGQUxTRQogICAgbnVtYmVyX3NlY3Rpb25zOiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCnRoZW1lOiAiZmxhdGx5IgotLS0KCmBgYHtyIGluY2x1ZGUgPSBGQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2UgPSBGQUxTRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSBGQUxTRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KHNpemUgPSAic2NyaXB0c2l6ZSIpCmBgYAoKQnVpbHQgd2l0aCBSIHZlcnNpb24gYHIgZ2V0UnZlcnNpb24oKWAuCgojIEludHJvZHVjdGlvbgoKVGhlIHB1cnBvc2Ugb2YgdGhpcyBkb2N1bWVudCBpcyB0byBtYWtlIG9wZW4gYW5kIHNoYXJlLWFibGUgdGhlIHJlc2VhcmNoIG1ldGhvZHMgdXNlZCBmb3IgbXkgZGlzc2VydGF0aW9uIG9uIG5lYXJzaG9yZSBmaXNoIGNvbW11bml0aWVzIGluIEFsYXNrYSB3b3JraW5nIHRvd2FyZHMgYSBQaEQgaW4gbWFyaW5lIGJpb2xvZ3kgYXQgdGhlIFVuaXZlcnNpdHkgb2YgQWxhc2thIEZhaXJiYW5rcy4gSGVyZSwgSSBjb3ZlciBzdGVwcyBvZiB0aGUgZGF0YSBwcmVwYXJhdGlvbiBmb3IgbXkgc2Vjb25kIGFuZCB0aGlyZCBjaGFwdGVycyBjb25jZXJuaW5nIHNwYXRpYWwgYW5kIHRlbXBvcmFsIGRpc3RyaWJ1dGlvbnMgb2YgbmVhcnNob3JlIGZpc2hlcyBhY3Jvc3MgdGhlIHN0YXRlLiBUaGlzIGFuZCBvdGhlciBmaWxlcyBjYW4gYmUgYWNjZXNzZWQgdmlhIHRoZSBLYWNoZW1hayBCYXkgTmF0aW9uYWwgRXN0dWFyaW5lIFJlc2VhcmNoIFJlc2VydmUncyBnaXRodWIgW25lYXJzaG9yZSBmaXNoIHJlcG9zaXRvcnldKGh0dHBzOi8vZ2l0aHViLmNvbS9rYm5lcnIvbmVhcnNob3JlLWZpc2gpLgoKSW4gdGhpcyBkb2N1bWVudCBJIHNoYXJlIGV4cGxvcmF0b3J5IGRhdGEgYW5hbHlzZXMgY29uZHVjdGVkIG9uIHRoZSBOT0FBIE5lYXJzaG9yZSBGaXNoIEF0bGFzIChORkEpIGRhdGFiYXNlLiBUaGUgTkZBIGRhdGFiYXNlIGNhbiBiZSBmb3VuZCBoZXJlLCA8aHR0cHM6Ly9hbGFza2FmaXNoZXJpZXMubm9hYS5nb3YvbWFwcGluZy9zei8+LiBOYW1lbHksIHRoaXMgZG9jdW1lbnQgY29udGFpbnMgdGhlIHN0ZXBzIHRha2VuIGFmdGVyIGNsZWFuaW5nL3dyYW5nbGluZyByYXcgZGF0YS4gSW4gcGFydGljdWxhciBJIHByb2R1Y2UgdmFyaW91cyB2aXN1YWxpemF0aW9ucyBvZiB0aGUgZGF0YSBpbiBzcGFjZSBhbmQgdGltZS4gSW5pdGlhbCB3cmFuZ2xlIHN0ZXBzIGNhbiBiZSB2aWV3ZWQgYXQgdGhpcyBbUnB1YnMgcGFnZV0oaHR0cHM6Ly9ycHVicy5jb20vY2hndW8xLzExODg2MTQpIGFuZCBpdHMgZGF0YSBvYmplY3RzIGFyZSBzb3VyY2VkIGJlbG93IChmaWxlICJORkEucmRhIikuCgojIyBTZXQgdXAKCkxvYWQgcmVxdWlyZWQgcGFja2FnZXMsIGRlZmluZSBkaXJlY3RvcnksIHNldCBvcHRpb25zLCBzb3VyY2UvbG9hZCBmaWxlczoKCmBgYHtyIHJlc3VsdHMgPSAnaGlkZSd9CiMgUGFja2FnZXMKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGhlcmUpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCgojIERpcmVjdG9yeQp3ZCA9IGhlcmUoKQpkaXJzID0gd2QgJT4lIGxpc3QuZmlsZXMoKSAlPiUgc3RyX3N1YnNldChwYXR0ZXJuID0gIl5SRUFETUV8XkxJQ0VOU0V8Lm1kJHwuUnByb2okIiwgbmVnYXRlID0gVFJVRSkKZm9yIChpIGluIHNlcV9hbG9uZyhkaXJzKSkgewogIG5hbWUgPSBzdHJfcmVwbGFjZV9hbGwoZGlyc1tpXSwgIl4iLCAiZGlyLiIpCiAgcGF0aCA9IHN0cl9yZXBsYWNlX2FsbChkaXJzW2ldLCAiXiIsIHN0cl9jKHdkLCAiLyIpKQogIGFzc2lnbihuYW1lLCBwYXRoKQogIHJtKG5hbWUsIHBhdGgsIGkpCn0KCiMgT3B0aW9ucwoKIyBTb3VyY2UvTG9hZApsb2FkKGZpbGUucGF0aChkaXIuZGF0YSwgIk5GQV93cmFuZ2xlZC5yZGEiKSkgIyB3cmFuZ2xlZCBkYXRhCmBgYAoKIyMgQmFja2dyb3VuZCBhbmQgb2JqZWN0aXZlcwoKQmFzZWQgb24gbXkgb3duIHJlc2VhcmNoIGFuZCByZWxhdGVkIGxpdGVyYXR1cmUsIEkgY2FuIGJyb2FkbHkgaW50ZXJwcmV0IHRoZXNlIGJlYWNoIHNlaW5lIGRhdGEgaW4gYSBzcGF0aW90ZW1wb3JhbCBjb250ZXh0LiBEZXBlbmRpbmcgb24gd2hlbiAodGltZSBvZiB5ZWFyKSBhbmQgd2hlcmUgKGxvY2F0aW9uIGFuZCBoYWJpdGF0KSwgSSBoYXZlIGEgZ2VuZXJhbCBzdHJ1Y3R1cmUgaW4gbWluZCBvZiB0aGUgZGl2ZXJzaXR5IG9mIHRoZSBjb21tdW5pdHkuIERlcGVuZGluZyBvbiB3aG8ncyB0aGVyZSwgSSBoYXZlIGEgcm91Z2ggZ3Vlc3Mgb2YgdGhlIHJlbGF0aXZlIGFidW5kYW5jZSBvZiBlYWNoIGNvbW11bml0eSBtZW1iZXIgKGF0IGxlYXN0IGZvciB0aGUgbW9yZSBjb21tb25seSBjYXVnaHQgb25lcykuIE15IGhvcGUgd2l0aCB3b3JraW5nIHdpdGggdGhlIE5GQSBkYXRhIGlzIHRoYXQgdGhpcyBicm9hZCB1bmRlcnN0YW5kaW5nIGNhbiBiZSBmb3JtYWxseSB0ZXN0ZWQgd2l0aCBpbmZlcmVuY2UgYW5kIHN0YXRpc3RpY3MsIGFuZCB0aGF0IG1vcmUgaW5mb3JtYXRpdmUgcmVzZWFyY2ggcXVlc3Rpb25zIGNhbiBiZSBhbnN3ZXJlZC4KCkZpbmRpbmdzIGZyb20gb3RoZXIgbmVhcnNob3JlIGZpc2ggcmVzZWFyY2hlcnMgbGFyZ2VseSBhZ3JlZSB0aGF0IHNlYXNvbmFsaXR5IChvciBzb21lIHJlbGF0ZWQgZW52aXJvbm1lbnRhbCBjb25kaXRpb24pIGlzIGEgc3Ryb25nIHByZWRpY3RvciBvZiBjb21tdW5pdHkgb3Igc3BlY2llcyBwcmVzZW5jZS4gSW50ZXJhbm51YWwgZGlmZmVyZW5jZXMgY2FuIGV4aGliaXQgd2lkZSB2YXJpYWJpbGl0eSBhbmQgc2hvdWxkIGJlIGFjY291bnRlZCBmb3Igd2hlbmV2ZXIgcG9zc2libGUuIEFuZCBhdCBsYXJnZXIgdGltZS1zY2FsZXMgKGUuZy4sIGRlY2FkYWwpLCBjb21tdW5pdGllcyBleGhpYml0IGNoYW5nZXMgd2hpY2ggbWF5IHJlbGF0ZSB0byByZWdpbWUgc2hpZnRzIG9jY3VycmluZyBtb3JlIGJyb2FkbHkgdGhhbiB0aGUgbmVhcnNob3JlLgoKU3BhdGlhbGx5LCBsYXJnZS1zY2FsZSAocmVnaW9uYWwpIGVmZmVjdHMgYXBwZWFyIHRvIGJlIGFzIG9yIG1vcmUgaW1wb3J0YW50IHRoYW4gc3ViLXJlZ2lvbmFsIG9yIGxvY2FsLXNjYWxlIGVmZmVjdHMuIEhvd2V2ZXIsIG1hbnkgc3R1ZGllcyBhbHNvIGZpbmQgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwcyBpbiBjb21tdW5pdHkgcmVzcG9uc2UgYXQgdGhlc2Ugc21hbGxlciBzY2FsZXMuIExpa2VseSwgdGhlIG1vc3QgYXBwcm9wcmlhdGUgc3BhdGlhbCBjb25zaWRlcmF0aW9uIGRlcGVuZHMgb24gdGhlIHF1ZXN0aW9uIGJlaW5nIGFza2VkLiBTbyBtYXliZSBhIG1vcmUgYXBwcm9wcmlhdGUgcXVlc3Rpb24gdG8gYXNrIG9mIHRoZSBORkEgZGF0YSBpcyBpZiB0aGVyZSBhbnkgc2lnbmlmaWNhbnQgc3BhdGlhbCBzY2FsZXMgZGlzY2VybmlibGUgaW4gdGhlIGRhdGEsIGFuZCBhbHNvIGhvdyBzaG91bGQgd2UgYWRkcmVzcyB0aG9zZSBzY2FsZXMgaW4gZnV0dXJlIHJlc2VhcmNoLCBzdWNoIGFzIHN0dWRpZXMgb24gc3Vic2V0cyBvZiB0aGUgdGF4YSBvciBoYWJpdGF0IG1hbmFnZW1lbnQgY29uc2lkZXJhdGlvbnMuCgpJJ2xsIHN0YXJ0IGJ5IGV4cGxvcmluZyB0aGUgc3RydWN0dXJlIG9mIG91ciAndmlzaXRzJyBkYXRhZnJhbWUsIGFuZCB0aGVuIEknbGwgbW92ZSBvbiB0byB2aXN1YWxpemluZyB0aGUgaW5mb3JtYXRpb24gZGVyaXZlZCBmcm9tIG91dCAnY2F0Y2gnIGRhdGFmcmFtZS4KCiMgRXhwbG9yaW5nIHZpc2l0IGRhdGEKCiMjIFN1bW1hcnkgb2YgdmlzaXRzCgpSZW1lbWJlciB0aGF0IGluIHRoZSBkYXRhIHdyYW5nbGluZyBzdGFnZSwgd2UgY3JlYXRlZCBhIG5ldyBzYW1wbGUgaWRlbnRpZmllciBiYXNlZCBvbiBzaXRlIGFuZCBkYXRlIHdoaWNoIHdlIGNhbGxlZCBWaXNpdElELiBMZXQncyB0YWtlIGEgbG9vayBhdCB0aGUgdmFyaWFibGVzIGFzc29jaWF0ZWQgd2l0aCBlYWNoIFZpc2l0SUQ6CgpgYGB7cn0KZ2xpbXBzZSh2aXNpdHMpCmBgYAoKRHVyaW5nIHRoZSB3cmFuZ2xpbmcgc3RhZ2UsIEkgZGVjaWRlZCB0aGF0IFJlcGxpY2F0ZXMgYW5kIE1lc2hTaXplIHNob3VsZCBiZSB0aGUgbWFpbiBjb3ZhcmlhdGVzIHRoYXQgbmVlZGVkIGNvbnNpZGVyYXRpb24uIEF0IHRoaXMgcG9pbnQgdGhleSBhcmUgY2xhc3NlZCBhcyBpbnRlZ2Vycy9udW1iZXJzLCBidXQgd2Ugd2lsbCBwcm9iYWJseSB3YW50IHRoZW0gdG8gYmUgZmFjdG9ycyBpbnN0ZWFkLiBDbHVzdGVyIGlzIGEgYnlwcm9kdWN0IG9mIGNsdXN0ZXJpbmcgc29tZSBzaXRlcyB0b2dldGhlciwgc28gaXQgbWF5IG5vdCBiZSBuZWVkZWQgaWYgd2UncmUgdXNpbmcgTGF0L0xvbiBhcyBvdXIgcHJpbWFyeSBleHBsYW5hdG9yeSB2YXJpYWJsZS4gU3RpbGwsIGl0IGNvdWxkIGJlIGEgdXNlZnVsIGdyb3VwaW5nIGZhY3RvciBsYXRlciBvbi4gRGF0ZSB3aWxsIGxpa2VseSBiZSBtdXRhdGVkIGludG8gbXVsdGlwbGUgYWRkaXRpb25hbCBwZXJpb2RzIChkYXkgb2YgeWVhciwgbW9udGgsIHllYXIpIHRvIHNlZSBpZiBhbnkgb2YgdGhvc2UgZmFjdG9ycyBhcmUgdXNlZnVsIGluIGV4cGxhaW5pbmcgZmlzaCBkYXRhLiBXZSdsbCBhZGRyZXNzIGVkaXRzIHRvIHRoZXNlIHZhcmlhYmxlcyBhcyB0aGV5IGNvbWUgdXAgaW4gb3VyIGV4cGxvcmF0aW9uLgoKIyMgU3BhdGlhbCBkaXN0cmlidXRpb24KCmBgYHtyfQpsZWFmbGV0KHZpc2l0cykgJT4lIAogIGFkZFRpbGVzKG9wdGlvbnMgPSB0aWxlT3B0aW9ucyhtaW5ab29tID0gMy41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXggPSAwLjUpKSAlPiUKICBzZXRWaWV3KGxhdCA9IDY1LCBsbmcgPSAtMTUyLCB6b29tID0gMy41KSAlPiUKICBhZGRTaW1wbGVHcmF0aWN1bGUoaW50ZXJ2YWwgPSA1KSAlPiUgIAogIGFkZENpcmNsZU1hcmtlcnMobG5nID0gfkxvbiwgbGF0ID0gfkxhdCwKICAgICAgICAgICAgICAgICAgIHN0cm9rZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgcG9wdXAgPSB+VmlzaXRJRCwKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSkKYGBgCgpJbiB0aGUgbWFwIGFib3ZlIHdlIGNhbiB2aWV3IGFsbCBvZiBvdXIgc2FtcGxlcyBmcm9tIGFjcm9zcyBBbGFza2EuIExlYWZsZXQgb3B0aW9ucyBhcmUgbmljZSBiZWNhdXNlIHlvdSBjYW4gb3B0aW9uYWxseSBncm91cCBzYW1wbGVzIG9uIHRoZSBtYXAgYW5kIHNob3cgYSBib3VuZGFyeSBwb2x5Z29uIG9mIHRoZSBhcmVhIHRoZXkgY292ZXIgd2hlbiB5b3UgaG92ZXIgb3ZlciB0aGVpciBpY29uLiBBdCB0aGUgbWluaW11bSB6b29tIGxldmVsICgzLjUpLCB3ZSBzZWUgdGhlIGxhcmdlc3QgZ3JvdXAgc3Bhbm5pbmcgbmVhcmx5IGFsbCBvZiBTb3V0aGVhc3QgQWxhc2thLCBmb2xsb3dlZCBieSBhIGdyb3VwIGluIFNvdXRoY2VudHJhbCB0aGF0IGNvdmVycyBQcmluY2UgV2lsbGlhbSBTb3VuZCwgQ29vayBJbmxldCwgYW5kIHRoZSBub3J0aGVybiBoYWxmIG9mIEtvZGlhayBJc2xhbmQuIFRoZSB0aGlyZCBsYXJnZXN0IGdyb3VwIGZvcm1zIGEgbXVjaCBzbWFsbGVyIHBvbHlnb24gYXJlYSBhcm91bmQgVXRxaWFndmlrLiBGcm9tIHRoZXJlLCB3ZSBzZWUgZXZlbiBzbWFsbGVyIGdyb3VwcyBmcm9tIHRoZSBFYXN0ZXJuIEJlYXVmb3J0IFNlYSBhcm91bmQgS2FrdG92aWssIHRoZSBCZXJpbmcgU3RyYWl0IGFuZCBTb3V0aGVybiBDaHVrY2hpIFNlYSBuZWFyIEtvdHplYnVlLCBhbmQgQnJpc3RvbCBCYXkuIFRoZXJlIGFyZSBhbHNvIHR3byBncm91cHMgZnJvbSB0aGUgQWxhc2thIFBlbmluc3VsYSBhbmQgQWxldXRpYW4gSXNsYW5kcywgb25lIGZvY3VzZWQgYXJvdW5kIEFkYWsgYW5kIGFub3RoZXIgc3Bhbm5pbmcgZnJvbSBTYW5kIFBvaW50IHRvIFVuYWxhc2thLiBXZSBjYW4gc2VlIGhvdyBzdWJzZXRzIG9mIHRoZSBzYW1wbGVzIGNoYW5nZSBieSB6b29taW5nIGluLiBXaGVuIHRoZXJlIGFyZSBzaW5nbGUgc2FtcGxlcyBpbiB2aWV3LCBob3ZlcmluZyBvdmVyIHRob3NlIHdpbGwgdGVsbCB1cyBpdHMgVmlzaXRJRCBuYW1lLgoKT2J2aW91c2x5LCB0aGlzIHZpc3VhbGl6YXRpb24gb2YgdGhlIGRhdGEgaXMgbm90IHBlcmZlY3QgYW5kIHByZXR0eSByb3VnaC0gbm90ZSB0aGF0IHRoZSBncm91cHMgYXJlIGZvcm1lZCBieSB0aGUgb3ZlcmxhcCBvZiBzYW1wbGVzIGJhc2VkIG9uIHBpeGVsIHJhZGl1cyAoMTApLiBGb3IgZXhhbXBsZSwgdGhlIHBvbHlnb24gb2Ygc2FtcGxlcyBmcm9tIEJyaXN0b2wgQmF5IGF0IHRoZSBtaW5pbXVtIHpvb20gbGV2ZWwgYWN0dWFsbHkgY3Jvc3NlcyB0aGUgQWxhc2thIFBlbmluc3VsYSB0byBpbmNsdWRlIGEgc2FtcGxlIGZyb20gQWdoaXl1ayBJc2xhbmQuIEFsdGhvdWdoLCB0aGUgbWFwIGlzIHVzZWZ1bCBpbiBnYWluaW5nIGEgZ2VuZXJhbCB1bmRlcnN0YW5kaW5nIG9mIHRoZSBleGlzdGluZyBjbHVzdGVycyBvZiBzYW1wbGVzIHdpdGhpbiB0aGUgTkZBIGRhdGFiYXNlLgoKIyMgUmVnaW9ucwoKV2UgbWF5IHdhbnQgdG8gZGVmaW5lIGEgc3BhdGlhbCBmYWN0b3IgYmFzZWQgb24gdGhlc2Ugcm91Z2ggZ3JvdXBpbmdzIGFzIGEgc3RhcnRpbmcgcGxhY2UgdG8gc2VlIGlmIHRoZSBzbWFsbGVyLCBtb3JlIGlzb2xhdGVkIGdyb3VwcyBzaG91bGQgYmUgbHVtcGVkIHdpdGggb3RoZXIgZ3JvdXBzIG9yIG5vdC4gQWN0dWFsbHksIHRoZSBORkEgYWxyZWFkeSBoYXMgYSBSZWdpb24gY2xhc3NpZmllciBwZXIgc2l0ZSwgYnV0IHRoZSByZWFzb24gSSBkbyBub3Qgd2FudCB0byB1c2UgaXQgaXMgYmVjYXVzZSB0aGV5IGxpbmtlZCBSZWdpb24gdG8gU2l0ZUlELiBXaGVuIHdlIGNyZWF0ZWQgb3VyIG5ldyBWaXNpdElELCBzb21lIHNhbXBsZXMgbm93IGNvbnRhaW5lZCB0d28gUmVnaW9uIGxhYmVscy0gdGhlc2Ugd2VyZSBtb3N0bHkgY2FzZXMgZnJvbSBhcm91bmQgVXRxaWFndmlrIHdoZXJlIHNvbWUgd2VyZSBsYWJlbGxlZCBhcyBDaHVja2NoaSBhbmQgb3RoZXJzIGFzIEJlYXVmb3J0IGJ1dCBhY3R1YWxseSBvY2N1cnJlZCBvbiB0aGUgc2FtZSBkYXkgYW5kIHdpdGhpbiBhIHZlcnkgc2hvcnQgZGlzdGFuY2Ugb2YgZWFjaCBvdGhlci4KCkluc3RlYWQgb2YgdXNpbmcgdGhlIHRoZSBnaXZlbiByZWdpb25hbCBjbGFzc2VzLCBsZXQncyBqdXN0IG1ha2Ugb3VyIG93biB2YXJpYWJsZSBjYWxsZWQgJ1JlZ2lvbicgYW5kIGFkZCBpdCB0byB0aGUgb3VyIHZpc2l0cyBkZjoKCmBgYHtyfQojIFN0YXJ0IHdpdGggZXZlbnRzIHNvIHRoYXQgd2UgY2FuIG1ha2UgdXNlIG9mIExvY2F0aW9uIGluZm8gZm9yIHVuaXF1ZSBjYXNlcywKcmVnaW9ucyA9IGV2ZW50cyAlPiUKICBzZWxlY3QoRXZlbnRJRCwgVmlzaXRJRCwgTGF0LCBMb24sIExvY2F0aW9uKSAlPiUKICBtdXRhdGUoUmVnaW9uID0gY2FzZV93aGVuKExhdCA+IDY5ICYgTGF0IDwgODAgJiBMb24gPiAtMTUwICYgTG9uIDwgLTE0MCB+ICJCZWF1Zm9ydCBFYXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhdCA+IDY5ICYgTGF0IDwgODAgJiBMb24gPiAtMTYwICYgTG9uIDwgLTE1MCB+ICJDaHVrY2hpL0JlYXVmb3J0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhdCA+IDY1ICYgTGF0IDwgNjkgJiBMb24gPiAtMTcwICYgTG9uIDwgLTE2MCB+ICJDaHVrY2hpIFNvdXRoIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhdCA+IDU3ICYgTGF0IDwgNjAgJiBMb24gPiAtMTY1ICYgTG9uIDwgLTE1NSB+ICJCcmlzdG9sIEJheSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYXQgPiA1MCAmIExhdCA8IDU1ICYgTG9uID4gLTE4MCAmIExvbiA8IC0xNzUgfiAiQWxldXRpYW5zIEFkYWsiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTGF0ID4gNTAgJiBMYXQgPCA1NSAmIExvbiA+IC0xNzAgJiBMb24gPCAtMTY1IH4gIkFsZXV0aWFucyBVbmFsYXNrYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYXQgPiA1NSAmIExhdCA8IDY1ICYgTG9uID4gLTE1NSAmIExvbiA8IC0xNDUgfiAiR09BIFNvdXRoY2VudHJhbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYXQgPiA1MyAmIExhdCA8IDYxICYgTG9uID4gLTE0OCAmIExvbiA8IC0xMzAgfiAiR09BIFNvdXRoZWFzdCIpKQoKIyBDaGVjayB3aGljaCBzYW1wbGVzIHdlIG1pc3NlZCwKZmlsdGVyKHJlZ2lvbnMsIGlzLm5hKFJlZ2lvbikpCgojIExldCdzIGFkZHJlc3MgdGhvc2UgdXNpbmcgTG9jYXRpb24sCnJlZ2lvbnMgPSBtdXRhdGUocmVnaW9ucywKICAgICAgIFJlZ2lvbiA9IGNhc2Vfd2hlbighaXMubmEoUmVnaW9uKSB+IFJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpcy5uYShSZWdpb24pICYgc3RyX2RldGVjdChMb2NhdGlvbiwgIll1bmFza2EiKSB+ICJBbGV1dGlhbnMgWXVuYXNrYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoUmVnaW9uKSAmIHN0cl9kZXRlY3QoTG9jYXRpb24sICJBZ2hpeXVrIikgfiAiQWxldXRpYW5zIEFnaGl5dWsiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKFJlZ2lvbikgJiBzdHJfZGV0ZWN0KExvY2F0aW9uLCAiU2h1bWFnaW4iKSB+ICJBbGV1dGlhbnMgU2h1bWFnaW4iKSkKCiMgQ2hlY2sgYWdhaW4gKHNob3VsZCBiZSAwKSwKZmlsdGVyKHJlZ2lvbnMsIGlzLm5hKFJlZ2lvbikpICU+JSBucm93KCkKYGBgCgpOb3cgbGV0J3MgYWRkIFJlZ2lvbiBhcyBhIGZhY3RvciB0byBvdXIgdmlzaXRzIGRmLCBhbmQgc2hvdyBpdCBvbiBhIG1hcC4gU2luY2Ugd2UncmUgbWFuaXB1bGF0aW5nIG91ciBkYXRhIG9iamVjdHMgYWdhaW4sIGxldCdzIGFsc28gcmVuYW1lIHZpc2l0cyBzbyB0aGF0IHdlIGNhbiBrZWVwIHRyYWNrIG9mIG91ciBjaGFuZ2VzLgoKYGBge3J9CiMgQ2FsbCBvdXIgd3JhbmdsZWQgZGYgdmVyc2lvbiB2aXNpdHMuMCBhbmQgcmVtb3ZlIHRoZSBub24tdmVyc2lvbiAndmlzaXRzJyBpZiBpdCdzIHRoZXJlLAppZiAoInZpc2l0cyIgJWluJSBscygpKSBhc3NpZ24oInZpc2l0cy4wIiwgdmlzaXRzKQppZiAoInZpc2l0cyIgJWluJSBscygpKSBybSh2aXNpdHMpCgojIE1ha2UgUmVnaW9uIGEgZmFjdG9yIGFuZCBqb2luIGJ5IFZpc2l0SUQsCnZpc2l0cy4xID0gcmVnaW9ucyAlPiUKICBzZWxlY3QoVmlzaXRJRCwgUmVnaW9uKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIG11dGF0ZShSZWdpb24gPSBhcy5mYWN0b3IoUmVnaW9uKSkgJT4lCiAgbGVmdF9qb2luKHZpc2l0cy4wLCAuLCBieSA9ICJWaXNpdElEIikKCiMgRnVuY3Rpb24gZm9yIHJlZ2lvbmFsIHBhbGV0dGUKcGFsZXR0ZS5yZWdpb24gPSBjb2xvckZhY3RvcihwYWxldHRlID0gYnJld2VyLnBhbChuID0gdmlzaXRzLjEkUmVnaW9uICU+JSBuX2Rpc3RpbmN0KCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICdTcGVjdHJhbCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbiA9IGZhY3Rvcih2aXNpdHMuMSRSZWdpb24pKQoKIyBNYXAKbGVhZmxldCh2aXNpdHMuMSkgJT4lIAogIGFkZFRpbGVzKCkgJT4lCiAgYWRkQ2lyY2xlTWFya2VycyhsbmcgPSB+TG9uLCBsYXQgPSB+TGF0LAogICAgICAgICAgICAgICAgICAgY29sb3IgPSB+cGFsZXR0ZS5yZWdpb24oUmVnaW9uKSwKICAgICAgICAgICAgICAgICAgIGZpbGxDb2xvciA9IH5wYWxldHRlLnJlZ2lvbihSZWdpb24pLAogICAgICAgICAgICAgICAgICAgcG9wdXAgPSB+cGFzdGUoUmVnaW9uLCBWaXNpdElEKSwKICAgICAgICAgICAgICAgICAgIHN0cm9rZSA9IEZBTFNFKSAlPiUKICBhZGRMZWdlbmQocG9zaXRpb24gPSAidG9wcmlnaHQiLAogICAgICAgICAgICBwYWwgPSBwYWxldHRlLnJlZ2lvbiwgdmFsdWVzID0gflJlZ2lvbiwKICAgICAgICAgICAgdGl0bGUgPSAiUmVnaW9uIiwKICAgICAgICAgICAgb3BhY2l0eSA9IDAuNzUpCmBgYAoKYGBge3IgZWNobyA9IEZBTFNFfQojIE51bWJlciBvZiBzYW1wbGVzIHBlciBSZWdpb24Kc2VsZWN0KHZpc2l0cy4xLCBWaXNpdElELCBSZWdpb24pICU+JQogIGNvdW50KFJlZ2lvbikgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBnZ3Bsb3QoLiwgYWVzKHggPSBSZWdpb24sIHkgPSBuLCBmaWxsID0gUmVnaW9uKSkgKwogIGdlb21fY29sKCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgdmp1c3QgPSAtMC41KSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgdGl0bGUgPSAiTm8uIHNhbXBsZXMgcGVyIFJlZ2lvbiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKTGlrZSB3ZSBzYXcgYmVmb3JlLCB0aGUgbWFqb3JpdHkgb2Ygb3VyIHNhbXBsZXMgYXJlIGxvY2F0ZWQgaW4gdGhlIEd1bGYgb2YgQWxhc2thIChHT0EpLCBuYW1lbHkgU291dGhlYXN0IChTRUFrKSBhbmQgU291dGhjZW50cmFsIChTQ0FLKS4gSWYgd2Ugd2VyZSB0byBsb29rIGF0IGRpZmZlcmVuY2VzIGluIGNhdGFjaCBpbiB0aGUgR09BLCBpdCdkIGJlIGNvb2wgaWYgd2UgY291bGQgaW5jbHVkZSB0aGUgQWxldXRpYW4gc2FtcGxlcyB0b28uIE9idmlvdXNseSwgd2UnbGwgd2FudCB0byBhZGRyZXNzIHRob3NlIGZldyBpbnN0YW5jZXMgZnJvbSBBZ2hpeXVrLCBTaHVtYWdpbiwgYW5kIFl1bmFza2EsIGFuZCBpZGVhbGx5IHdlIGFnZ3JlZ2F0ZSB0aGVtIGludG8gb25lIG9yIHR3byBncm91cHMuIFdlIGFsc28gc2VlIHJlbGF0aXZlbHkgc21hbGwgc2FtcGxlIHNpemVzIGZyb20gQnJpc3RvbCBCYXkgYW5kIGZyb20gRWFzdCBCZWF1Zm9ydCwgd2hpY2ggbWF5IG9yIG1heSBub3QgYmUgcHJvaGliaXRpdmUgaW4gY29uZHVjdGluZyBtZWFuaW5nZnVsIHRlc3RzLiBPbmUgb3RoZXIgY29uc2lkZXJhdGlvbiBpcyB0aGUgY291cGxlIG9mIHNhbXBsZXMgYWxvbmcgdGhlIEJlcmluZyBTdHJhaXQgY29hc3Qgd2hpY2ggYXJlIGx1bXBlZCB0b2dldGhlciB3aXRoIGEgbGFyZ2VyIGNvbmNlbnRyYXRpb24gb2Ygc2FtcGxlcyBmcm9tIFNvdXRoIENodWtjaGkuCgpTb21lIG9mIG91ciBmaXJzdCBhbmFseXNlcyBzaG91bGQgc2VlIGlmIHRoZSBtb3JlIGlzb2xhdGVkIHNhbXBsZXMgYXJlIGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlciBzYW1wbGVzLiBJZiBub3QsIHRoZW4gd2UgY2FuIGFnZ3JlZ2F0ZS4gSWYgeWVzLCB0aGVuIHdlIHNob3VsZCByZXBvcnQgYW55IHNpZ25pZmljYW50IHRlc3RzLgoKIyMgVGVtcG9yYWwgZGlzdHJpYnV0aW9uCgpOZXh0IHdlJ2xsIHdhbnQgdG8gdGFrZSBhIGxvb2sgYXQgaG93IG91ciBzYW1wbGVzIGRpc3RyaWJ1dGUgdGhyb3VnaG91dCB2YXJpb3VzIHRpbWUgcGVyaW9kcy4gVGhpcyB3aWxsIGdpdmUgdXMgYSBnb29kIGlkZWEgb2YgaG93IHdlbGwgb3VyIHNhbXBsZXMgbWF5IG9yIG1heSBub3Qgb3ZlcmxhcC0gcGFydGljdWxhcmx5LCB3ZSdsbCB3YW50IHRvIHNlZSBvdmVybGFwcyBpbiB5ZWFycyBhbmQgbW9udGhzIGZvciBiZXR0ZXIgY29tcGFyaXNvbnMgb2YgdGhlIGNhdGNoIGRhdGEuCgpgYGB7cn0KIyBGaXJzdCBjcmVhdGUgYSBkZiBzcGVjaWZpY2FsbHkgY29udGFpbmluZyBhdCB0aW1lIHZhcmlhYmxlcwp0aW1lcyA9IHZpc2l0cy4xICU+JQogIHNlbGVjdChWaXNpdElELCBEYXRlKSAlPiUKICBtdXRhdGUoWWVhciA9IHllYXIoRGF0ZSksCiAgICAgICAgIE1vbnRoID0gbW9udGgoRGF0ZSwgbGFiZWwgPSBUUlVFKSwKICAgICAgICAgV2VlayA9IHdlZWsoRGF0ZSksCiAgICAgICAgIERheSA9IHlkYXkoRGF0ZSkpCgojIFllYXIKdGltZXMgJT4lCiAgY291bnQoWWVhcikgJT4lCiAgZ2dwbG90KC4sIGFlcyh4ID0gWWVhciwgeSA9IG4pKSArCiAgZ2VvbV9jb2woKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCB2anVzdCA9IC0wLjUsIGNvbG9yID0gImJsdWUiKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIHRpdGxlID0gIk5vLiBzYW1wbGVzIHBlciBZZWFyIikKCiMgWWVhciB3aXRob3V0IDE5NzYKdGltZXMgJT4lCiAgZmlsdGVyKFllYXIgPiAxOTgwKSAlPiUKICBjb3VudChZZWFyKSAlPiUKICBnZ3Bsb3QoLiwgYWVzKHggPSBZZWFyLCB5ID0gbikpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gLTAuNSwgY29sb3IgPSAiYmx1ZSIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgdGl0bGUgPSAiTm8uIHNhbXBsZXMgcGVyIFllYXIgd2l0aG91dCAxOTc2IikKCiMgTW9udGgKdGltZXMgJT4lCiAgY291bnQoTW9udGgpICU+JQogIGdncGxvdCguLCBhZXMoeCA9IE1vbnRoLCB5ID0gbikpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHZqdXN0ID0gLTAuNSwgY29sb3IgPSAiYmx1ZSIpICsKICBsYWJzKHggPSBOVUxMLCB5ID0gTlVMTCwgdGl0bGUgPSAiTm8uIHNhbXBsZXMgcGVyIE1vbnRoIikKCiMgV2Vlawp0aW1lcyAlPiUKICBjb3VudChXZWVrKSAlPiUKICBnZ3Bsb3QoLiwgYWVzKHggPSBXZWVrLCB5ID0gbikpICsKICBnZW9tX2NvbCgpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIGhqdXN0ID0gLTAuMTUsIGFuZ2xlID0gOTAsIGNvbG9yID0gImJsdWUiKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIHRpdGxlID0gIk5vLiBzYW1wbGVzIHBlciBXZWVrIikKCiMgRGF5IG9mIFllYXIKdGltZXMgJT4lCiAgY291bnQoRGF5KSAlPiUKICBkaXN0aW5jdCgpICU+JQogIGdncGxvdCguLCBhZXMoeCA9IERheSwgeSA9IG4pKSArCiAgZ2VvbV9jb2woKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIHRpdGxlID0gIk5vLiBzYW1wbGVzIHBlciBEYXkgb2YgWWVhciIpCmBgYAoKQnkgeWVhciwgd2Ugc2VlIGEgbGFyZ2UgdmFyaWFiaWxpdHkgaW4gbnVtYmVyIG9mIHNhbXBsZXMsIGFzIHdlbGwgYXMgYSBsb25lIDE5NzYgeWVhciB3aGljaCBJIHJlY29nbml6ZSB0byBiZSBCbGFja2J1cm4ncyBkYXRhc2V0IGZyb20gTG93ZXIgQ29vayBJbmxldC4gVGhhdCAxOTc2IGlzIGFuIGludGVyZXN0aW5nIGRhdGFzZXQgdGhhdCBjb3VsZCBiZSB1c2VmdWwgZm9yIGEgbG9vayBhdCBjYXRjaGVzIG92ZXIgdGltZSBpbiB0aGF0IHNwZWNpZmljIGFyZWEsIGJ1dCBpdCdsbCBuZWVkIHRvIGJlIGV4Y2x1ZGVkIGZyb20gYW55IG90aGVyIGNvbXBhcmlzb25zLiBUaGUgbG93ZXN0IG51bWJlciBvZiBzYW1wbGVzIG9jY3VyIGluIDIwMTAsIDIwMjAsIGFuZCAyMDIxLiBXZSBtYXkgd2FudCB0byBwYXkgY2xvc2UgYXR0ZW50aW9uIHRvIHRoZXNlIHllYXJzIGluIGNhc2UgdGhleSBzaG93IHVwIGFzIG91dGxpZXJzLiBJdCBzZWVtcyB0aGF0IDE5OTYtMjAwMCBpcyBhIHBlcmlvZCBvZiBoZWF2eSBzYW1wbGluZywgZm9sbG93ZWQgYnkgdGhlIG1pZCAyMDEwcyBhbmQgc29tZXdoYXQgYWN0aXZlIHllYXIgaW4gMjAwNi4KCkJ5IG1vbnRoLCB3ZSBzZWUgYW4gb2J2aW91cyB1cHRpY2sgZHVyaW5nIHRoZSBzdW1tZXIgd2hpY2ggbWFrZXMgc2Vuc2UgZ2l2ZW4gd2ludGVyIGNvbmRpdGlvbnMgYWxvbmcgbW9zdCBvZiBBbGFza2EncyBjb2FzdCAobGlnaHQsIGljZSwgZXRjLikuIE1hcmNoIGFuZCBPY3RvYmVyIGFyZSBpbnRlcmVzdGluZyBtb250aHMgYmVjYXVzZSBvZiB0aGUgcG90ZW50aWFsIGZvciBpbXBhY3RzIG9uIGZpc2hlcyBkdXJpbmcgeWVhcnMgd2l0aCB3YXJtZXIgc2hvdWxkZXIgc2Vhc29ucy4gTm92ZW1iZXIgdGhydSBGZWJydWFyeSB3aWxsIGxpa2VseSBiZSByZW1vdmVkIGZvciBvdXIgcHVycG9zZXMuIE91ciBrZXkgbW9udGhzIGxvb2sgdG8gYmUgSnVuZSwgSnVseSBhbmQgQXVndXN0LCB3aXRoIHBvc3NpYmxlIGluY2x1c2lvbiBvZiBBcHJpbCwgTWF5LCBhbmQgU2VwdGVtYmVyLgoKSXQncyBpbnRlcmVzdGluZyBpZiB3ZSBsb29rIGF0IHRoZSBieS13ZWVrIGFuZCBieS1kYXkgZ3JhcGhzLCB3ZSBzZWUgYSBkaXAgaW4gc2FtcGxpbmcgYXJvdW5kIG1pZC1KdW5lL2Vhcmx5LUp1bHkuIE5vdCBzdXJlIHdoeSB0aGlzIGlzLSBtYXliZSByZWxhdGVkIHRvIG1vcmUgdGFyZ2V0aW5nIG9mIGp1dmVuaWxlIHNhbG1vbmlkcyBpbiBlYXJseSBKdW5lLCBvciBtYXliZSBzbyByZWR1Y2VkIGVmZm9ydCBhcm91bmQgdGhlIDR0aCBvZiBKdWx5IGhvbGlkYXkuCgojIyBZZWFyICYgbW9udGggYnkgcmVnaW9uCgpMZXQncyBub3cgc2VlIGhvdyBvdXIgc2FtcGxlcyBvdmVybGFwIGJ5IFJlZ2lvbiBhbmQgWWVhciwgYW5kIGJ5IFJlZ2lvbiBhbmQgTW9udGguIEZvciB0aGVzZSBwdXJwb3NlcywgbGV0J3MgY29tYmluZSB0aGUgQWxldXRpYW5zIGludG8gb25lIGdyb3VwIGZvciBub3csIGFuZCByZW1vdmUgdGhlIDE5NzYgZGF0YS4KCmBgYHtyfQojIFNhbXBsZXMgYnkgWWVhciBhbmQgUmVnaW9uLApsZWZ0X2pvaW4oZmlsdGVyKHRpbWVzLCBZZWFyID4gMTk4MCksCiAgICAgICAgICBzZWxlY3QodmlzaXRzLjEsIFZpc2l0SUQsIFJlZ2lvbiksIGJ5ID0gIlZpc2l0SUQiKSAlPiUKICBtdXRhdGUoUmVnaW9uID0gY2FzZV93aGVuKHN0cl9kZXRlY3QoUmVnaW9uLCAiQWxldXRpYW5zIikgfiAiQWxldXRpYW5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICFzdHJfZGV0ZWN0KFJlZ2lvbiwgIkFsZXV0aWFucyIpIH4gUmVnaW9uKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGF0ZSwgeSA9IFJlZ2lvbiwgY29sb3IgPSBSZWdpb24pKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHNpemUgPSAwLjUsIGFscGhhID0gMC43NSkgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gInRleHQiLCB2anVzdCA9IC0xLjksIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiV5IiwKICAgICAgICAgICAgICAgZGF0ZV9icmVha3MgPSAiMiB5ZWFycyIpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiUmVnaW9uIiwKICAgICAgIHRpdGxlID0gIlNhbXBsZXMgYnkgWWVhciBhbmQgUmVnaW9uIiwKICAgICAgIHN1YnRpdGxlID0gIk5vLiBzYW1wbGVzIGNlbnRlcmVkIG92ZXIgbWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKIyBTYW1wbGVzIGJ5IE1vbnRoIGFuZCBSZWdpb24sCmxlZnRfam9pbihmaWx0ZXIodGltZXMsIFllYXIgPiAxOTgwKSwKICAgICAgICAgIHNlbGVjdCh2aXNpdHMuMSwgVmlzaXRJRCwgUmVnaW9uKSwgYnkgPSAiVmlzaXRJRCIpICU+JQogIG11dGF0ZShSZWdpb24gPSBjYXNlX3doZW4oc3RyX2RldGVjdChSZWdpb24sICJBbGV1dGlhbnMiKSB+ICJBbGV1dGlhbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIXN0cl9kZXRlY3QoUmVnaW9uLCAiQWxldXRpYW5zIikgfiBSZWdpb24pKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBNb250aCwgeSA9IFJlZ2lvbiwgY29sb3IgPSBSZWdpb24pKSArCiAgZ2VvbV9ib3hwbG90KCkgKwogIGdlb21faml0dGVyKHNpemUgPSAwLjUsIGFscGhhID0gMC43NSkgKwogIHN0YXRfc3VtbWFyeShnZW9tID0gInRleHQiLCB2anVzdCA9IC0xLjksIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSAiTW9udGgiLCB5ID0gIlJlZ2lvbiIsCiAgICAgICB0aXRsZSA9ICJTYW1wbGVzIGJ5IE1vbnRoIGFuZCBSZWdpb24iLAogICAgICAgc3VidGl0bGUgPSAiRXhjbHVkaW5nIDE5NzY7IG5vLiBzYW1wbGVzIGxhYmVsbGVkIGJ5IG1vbnRoIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCkludGVyZXN0aW5nIHRoYXQgZWFjaCByZWdpb24ncyBzYW1wbGVzIGNlbnRlciBvbiBhIGRpZmZlcmVudCB5ZWFyLiBBdCBhIGdsYW5jZSwgSSBzZWUgdGhlIG1vc3Qgb3ZlcmxhcCBpbiAyMDA2IHdoZXJlIHRoZSBBbGV1dGlhbnMgYW5kIGJvdGggR09BIHJlZ2lvbnMgbG9vayB0byBoYXZlIHNpbWlsYXIgc2FtcGxlIGRlbnNpdGllcywgcGx1cyB0aGVyZSBpcyBhIHNtYXR0ZXJpbmcgb2YgQ2h1a2NoaS9CZWF1Zm9ydCBzYW1wbGluZyB0b28uIEluIDIwMDksIHRoZSBCcmlzdG9sIEJheSBzYW1wbGVzIG1heSBiZSBjb21wYXJlZCB3aXRoIGJvdGggR29BIHJlZ2lvbnMgYW5kIHRoZSBDaHVrY2hpL0JlYXVmb3J0LCBhbHRob3VnaCB0aGUgc2FtcGxlcyBsb29rIG1vcmUgc3BhcnNlIGFjcm9zcyB0aGUgcmVnaW9ucy4gQW5kIGluIDIwMTMsIHRoZSBDaHVrY2hpL0JlYXVmb3J0IGhhcyBnb29kIG92ZXJsYXAgd2l0aCBib3RoIEdPQSByZWdpb25zIGFnYWluLiBJIHNlZSBuaWNlIHBlcmlvZHMgb2YgY29tcGFyaXNvbiBiZXR3ZWVuIFNFQUsgYW5kIFNDQUssIGJ1dCB0aGVyZSBpcyBhbHNvIGEgY29uY2VybmluZyBkaWZmZXJlbmNlIGluIHllYXJseSBkaXN0cmlidXRpb24gb2Ygc2FtcGxlcyBiZXR3ZWVuIHRoZSB0d28gcmVnaW9ucy4gRGVwZW5kaW5nIG9uIGhvdyBpbXBvcnRhbnQgeWVhciBlZmZlY3RzIGFwcGVhci0gd2UgbWF5IG5lZWQgdG8gdHJpbSB0aGUgZGF0YSBmb3IgYmV0dGVyIGNvbXBhcmlzb25zLgoKQnkgbW9udGgsIHdlIHNlZSB0aGF0IEF1Z3VzdCBjb250YWlucyBzYW1wbGVzIGZyb20gYWxsIHJlZ2lvbnMuIEp1bmUgaXMgdGhlIGNlbnRlciBmb3IgU0VBSyBhbmQgdGhlIEFsZXV0aWFucywgSnVseSBmb3IgU0NBSywgYW5kIEF1Z3VzdCBmb3IgQ2h1a2NoaS9CZWF1Zm9ydC4gQmVzdCBjb21wYXJpc29ucyBmcm9tIHRoaXMgbW9udGhseSB2aWV3IG1heSBiZSBhbiBBdWd1c3QgKG9yIGx1bXBlZCBKdWx5ICsgQXVndXN0KSBjb21wYXJpc29uIG9mIGFsbCBSZWdpb25zLiBBbHNvLCBhIEp1bmUgKG9yIGx1bXBlZCBKdW5lIHRocnUgQXVndXN0KSBjb21wYXJpc29uIG9mIEdPQSBhbmQgdGhlIEFsZXV0aWFucyB3b3VsZCBiZSBnb29kLiBBbmQsIHdlIHNob3VsZCBiZSBhYmxlIHRvIG5pY2VseSBjb21wYXJlIFNFQUsgYW5kIFNDQUsgZnJvbSBNYXkgdG8gU2VwdGVtYmVyLCBwb3RlbnRpYWxseSBpbmNsdWRpbmcgQXByaWwuCgpGb3Igbm93LCB3ZSdsbCBob2xkIG9mZiBvbiBleGNsdWRpbmcgYW55IG9mIHRoZSBkYXRhLiBJdCdsbCBiZSBiZXR0ZXIgdG8gcmV2aXNpdCB0aGVzZSBjb25zaWRlcmF0aW9ucyBhZnRlciBkZWNpZGluZyB3aGljaCByZXNlYXJjaCBxdWVzdGlvbnMgdG8gdGFja2xlLCBzbyBzdWJzZXRzIG9mIHRoZSBkYXRhIGNhbiBiZSBtYWRlIHNwZWNpZmljIHRvIGVhY2ggb25lLgoKIyMgTWVzaCBTaXplIGFuZCBSZXBsaWNhdGVzCgpMZXQncyBtYWtlIHNpbWlsYXIgdmlzdWFscyBhcyBiZWZvcmUsIGJ1dCBub3cgZm9jdXMgb24gTWVzaCBTaXplIGFuZCBSZXBsaWNhdGVzIGluIHNwYWNlIGFuZCB0aW1lLiBGaXJzdCwgd2UgY2FuIHJlLW1hcCB0aGUgc2FtcGxlcyB0byBjb2xvciBieSBNZXNoIFNpemUgYW5kIHNpemUgb2YgcG9pbnRzIHJlbGF0aXZlIFJlcGxpY2F0ZXMgKGxhcmdlIGRvdHMgPSBtb3JlIHJlcGxpY2F0ZXMpLgoKYGBge3J9CiMgUGFsZXR0ZSBmdW5jdGlvbiB0byBjb2xvciBtYXJrZXJzCnBhbGV0dGUubWVzaCA9IGNvbG9yRmFjdG9yKHBhbGV0dGUgPSBicmV3ZXIucGFsKG4gPSB2aXNpdHMuMSRNZXNoU2l6ZSAlPiUgbl9kaXN0aW5jdCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gJ1NwZWN0cmFsJyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbiA9IGZhY3Rvcih2aXNpdHMuMSRNZXNoU2l6ZSkpCiMgTWFwCmxlYWZsZXQodmlzaXRzLjEpICU+JSAKICBhZGRUaWxlcygpICU+JQogIGFkZENpcmNsZU1hcmtlcnMobG5nID0gfkxvbiwgbGF0ID0gfkxhdCwKICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9IH4oc3FydChSZXBsaWNhdGVzKjE1KSksCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IH5wYWxldHRlLm1lc2goTWVzaFNpemUpLAogICAgICAgICAgICAgICAgICAgZmlsbENvbG9yID0gfnBhbGV0dGUubWVzaChNZXNoU2l6ZSksCiAgICAgICAgICAgICAgICAgICBwb3B1cCA9IH5WaXNpdElELAogICAgICAgICAgICAgICAgICAgc3Ryb2tlID0gRkFMU0UpICU+JQogIGFkZExlZ2VuZChwb3NpdGlvbiA9ICJib3R0b21yaWdodCIsCiAgICAgICAgICAgIHBhbCA9IHBhbGV0dGUubWVzaCwgdmFsdWVzID0gfk1lc2hTaXplLAogICAgICAgICAgICB0aXRsZSA9ICJNZXNoIFNpemUgKG1tKSIsCiAgICAgICAgICAgIG9wYWNpdHkgPSAwLjc1KQpgYGAKCkkgaGF2ZSBhbiBpc3N1ZSBkaXNjZXJuaW5nIGFtb25nIHRoZSBzZXZlbiBkaWZmZXJlbnQgc2l6ZXMgc2luY2UgdGhvc2Ugd2FybWVyIGNvbG9ycyBkbyBub3QgZGl2ZXJnZSB3ZWxsLiBBbHRob3VnaCB0aGVyZSBhcmUgc29tZSBwYXR0ZXJucyB0byBtYWtlIG5vdGUgb2Y6IHRoZSBsYXJnZXN0IG1lc2ggc2l6ZSBvZiAxMi43IG9ubHkgb2NjdXJzIGluIGEgc21hbGwgYXJlYSBvZiBTRUFLLCB0aGUgMTAgbW0gc2FtcGxlcyBzaW1pbGFybHkgb25seSBvY2N1ciB3aXRoIHRoZSAxMi43IG1tIHNhbXBsZXMgKGxpa2VseSB0aGUgW0x1bmRzdHJvbSBldCBhbC4gMjAyMl0oaHR0cHM6Ly9kb2kub3JnLzEwLjEwMDcvczEyMjM3LTAyMi0wMTA1Ny14KSBnZWFyIGNvbXBhcmlzb24pLCBhbmQgdGhlIHNtYWxsZXN0IHNpemUgYXQgMyBtbSBvbmx5IG9jY3VycyBpbiBDb29rIElubGV0LiBJIGRvbid0IHNlZSBhbnkgb2J2aW91cyBzcGF0aWFsIHBhdHRlcm5zIGluIFJlcGxpY2F0ZXMsIGFsdGhvdWdoIHRoaXMgbWF5IG5vdCBiZSB0aGUgYmVzdCB2aWV3IG9mIGl0LgoKTGV0J3Mgc2VlIHRoZSBmcmVxdWVuY3kgb2Ygc2FtcGxlcyBmb3IgYm90aCB2YXJpYWJsZXM6CgpgYGB7cn0KIyBUYWJsZSB2aWV3CnRhYmxlKHZpc2l0cy4xJE1lc2hTaXplKQp0YWJsZSh2aXNpdHMuMSRSZXBsaWNhdGVzKQpgYGAKVGhlcmUgYXJlIG1vcmUgMTIuNyBtbSBzYW1wbGVzIHRoYW4gSSB3b3VsZCBoYXZlIGd1ZXNzZWQgd2hpY2ggaXMgYSBzaGFtZSBiZWNhdXNlIGlmIHRoZXkgYXJlIGNvbXBsZXRlbHkgZGlmZmVyZW50IHRoZW4gd2UgbG9zZSBhIGxvdCBvZiBzYW1wbGVzLiBJIGFtIHdvbmRlcmluZyBpZiBzaXplcyBhcmUgYWNjdXJhdGUtIEkgd291bGQgdGhpbmsgdGhhdCAzIG1tIGFuZCAzLjIgbW0gYXJlIGVmZmVjdGl2ZWx5IHNpbWlsYXIgaW4gcHJhY3RpY2UuIEkgYW0gYWxzbyB3b25kZXJpbmcgaWYgc29tZSBwcm9qZWN0cyByZXBvcnQsIHNheSAzIG1tIGluc3RlYWQgb2YgMy4yIG1tLCBiZWNhdXNlIG9mIHJvdW5kaW5nLiBJIHdvdWxkIGFzc3VtZSB0aGF0IHRoZSBuZXRzIHVzZWQgd2VyZSBtYW51ZmFjdHVyZWQgaW4gdGhlIFVTLCB3aGljaCB3b3VsZCBtZWFuIHRoYXQgc3BlY2lmaWNhdGlvbnMgYXJlIGdpdmVuIGluIHN0YW5kYXJkIG5vdCBtZXRyaWMuIExldCdzIGRvIGEgcXVpY2sgY2hlY2sgb24gaG93IHR5cGljYWwgbWVzaCBzaXplcyBjb252ZXJ0IGZyb20gaW5jaGVzIHRvIG1pbGxpbWV0ZXJzLgoKYGBge3J9CiMgRnVuY3Rpb24gYmFzZWQgb24gaW5jaCB0byBtaWxsaW1ldGVyIGNvbnZlcnNpb24KaW5fdG9fbW0gPSBmdW5jdGlvbiAoeCkgewogIHJldHVybih5ID0gMjUuNCAqIHgpCn0KCiMgVHlwaWNhbCBtZXNoIHNpemVzIGluIGluY2hlcwpzaXplcyA9IGMoKDEvOCksICgxLzQpLCAoMy84KSwgKDEvMiksICg1LzgpLCAoMy80KSkKCiMgQ29udmVydCB0byBtaWxsaW1ldGVycwppbl90b19tbShzaXplcykKYGBgCgpUaGVyZSBpcyBvYnZpb3VzbHkgc29tZSBmdW5ueSByb3VuZGluZyBoYXBwZW5pbmcgaW4gdGhlIGRhdGEuIEkgZG8gbm90IHNlZSBhbiBpc3N1ZSBieSBsdW1waW5nIG1lc2ggc2l6ZXMgdGhhdCBhcmUgd2l0aGluIG9uZSBtaWxsaW1ldGVyLiBFdmVuIGlmIHRoZSBuZXRzIHdlcmUgYWN0dWFsbHkgZGlmZmVyZW50IGJ5IGZyYWN0aW9ucyBvZiBhIG1pbGxpbWV0ZXIsIEkgZG9uJ3QgdGhpbmsgaXQgd291bGQgYWZmZWN0IHRoZSBzZWxlY3Rpdml0eSBvZiBmaXNoZXMgYWxsIHRoYXQgbXVjaC0gZXNwZWNpYWxseSBjb25zaWRlcmluZyB0aGF0IG1vc3Qgb2YgdGhlc2UgcmVzZWFyY2hlcnMgd2VyZSBjYXB0dXJpbmcgZmlzaCB0byBiZSBtZWFzdXJlZCB0byB0aGUgbmVhcmVzdCBtaWxsaW1ldGVyLgoKTGV0J3Mgc2VlIHRoYXQgbWFwIGFnYWluIHdpdGggdGhpcyBpbiBtaW5kOgoKYGBge3J9CiMgUGFsZXR0ZSBmdW5jdGlvbiBmb3IgYmlubmVkIHNpemVzCnBhbGV0dGUubWVzaC5iaW4gPSBjb2xvckJpbihwYWxldHRlID0gYnJld2VyLnBhbChuID0gNCwgbmFtZSA9ICdTcGVjdHJhbCcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluID0gdmlzaXRzLjEkTWVzaFNpemUgJT4lIHVuaXF1ZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmlucyA9ICBjKDAsIDQsIDcsIDExLCAxMykpCiMgTWFwCmxlYWZsZXQodmlzaXRzLjEpICU+JSAKICBhZGRUaWxlcygpICU+JQogIGFkZENpcmNsZU1hcmtlcnMobG5nID0gfkxvbiwgbGF0ID0gfkxhdCwKICAgICAgICAgICAgICAgICAgIHJhZGl1cyA9IH4oc3FydChSZXBsaWNhdGVzKjE1KSksCiAgICAgICAgICAgICAgICAgICBjb2xvciA9IH5wYWxldHRlLm1lc2guYmluKE1lc2hTaXplKSwKICAgICAgICAgICAgICAgICAgIGZpbGxDb2xvciA9IH5wYWxldHRlLm1lc2guYmluKE1lc2hTaXplKSwKICAgICAgICAgICAgICAgICAgIHBvcHVwID0gflZpc2l0SUQsCiAgICAgICAgICAgICAgICAgICBzdHJva2UgPSBGQUxTRSkgJT4lCiAgYWRkTGVnZW5kKHBvc2l0aW9uID0gImJvdHRvbXJpZ2h0IiwKICAgICAgICAgICAgY29sb3JzID0gYyhwYWxldHRlLm1lc2guYmluKDMpLAogICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUubWVzaC5iaW4oNiksCiAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZS5tZXNoLmJpbig5KSwKICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlLm1lc2guYmluKDEyKSksCiAgICAgICAgICAgIHZhbHVlcyA9IH5NZXNoU2l6ZSwKICAgICAgICAgICAgdGl0bGUgPSAiTWVzaCBTaXplIChtbSkiLAogICAgICAgICAgICBvcGFjaXR5ID0gMC43NSwKICAgICAgICAgICAgbGFiZWxzID0gYygiMyBvciAzLjIiLCAiNiBvciA2LjQiLCAiOS41IG9yIDEwIiwgIjEyLjciKSkKYGBgCgpNdWNoIGVhc2llciB0byByZWFkISBJIHNlZSBzb21lIGNvbmNlcm5pbmcgcGF0dGVybnMgd2UnbGwgd2FudCB0byBpbnZlc3RpZ2F0ZSBmdXJ0aGVyIGFzIHdlIGdvLiBUaGUgbWFqb3JpdHkgb2Ygc2FtcGxlcyBhcHBlYXIgdG8gYmUgdXNpbmcgdGhlIDMuMiBtbSBzaXplLCBpbmNsdWRpbmcgYm90aCBBcmN0aWMgZ3JvdXBzIHRoYXQgc2VlbSB0byB1c2UgaXQgZXhjbHVzaXZlbHkuIFRoZXJlIGlzIGEgbGFyZ2UgZGVuc2l0eSBvZiA2LjQgbW0gc2FtcGxlcyBpbiBOb3J0aGVybiBTRUFLIGFuZCB0aHJvdWdob3V0IHRoZSBBbGV1dGlhbnMuIFRoZSBzYW1lIGlzc3VlcyBhcmUgdmlzaWJsZSBjb25jZXJuaW5nIHRoZSB0d28gbGFyZ2VyIG1lc2ggc2l6ZXMuIFdlIHNob3VsZCBkbyBhIGNvbXBhcmlzb24gb2YgMy4yIG1tIGFuZCA2LjQgbW0gdG8gc2VlIGlmIHRoZXJlIGFyZSBhbnkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gY2F0Y2guCgpXaXRoIHRoZSBzaW1wbGVyIGNvbG9yIHNjaGVtZSwgSSBhbSBhbHNvIG5vdGljaW5nIHRoZSBkaWZmZXJlbmNlIGluIFJlcGxpY2F0ZXMgYSBsaXR0bGUgZWFzaWVyLiBKdXN0IGxvb2tpbmcgYXQgR09BIGFuZCBBbGV1dGlhbiBzYW1wbGVzLCBJIHNlZSB0aGF0IG1hbnkgb2YgdGhlIDYuNCBtbSBzYW1wbGVzIGFyZSBhbHNvIGxvdy1SZXBsaWNhdGUgc2FtcGxlcy4gQWx0aG91Z2gsIG1hbnkgb2Ygb3VyIHNhbXBsZXMgb25seSBjb250YWluIG9uZSByZXBsaWNhdGUgc28gdGhpcyBtYXkganVzdCBiZSBzb21ldGhpbmcgSSdtIHNlZWluZyBhbmQgbm90IGFjdHVhbGx5IGEgY29uY2Vybi4KCkxldCdzIHRha2UgYSBsb29rIGF0IGhvdyB0aGVzZSB2YXJpYWJsZXMgaW4gZ3JhcGhpY2FsIGZvcm1hdC4gSSdsbCBnbyBhaGVhZCBhbmQgYWdncmVnYXRlIHNpbWlsYXIgbWVzaCBzaXplcyBhbmQgcmUtY2xhc3NpZnkgdGhlIGJvdGggdmFyaWFibGVzIGFzIGZhY3RvcnMsIGFuZCBhZGQgaW4gdmFyaWFibGVzIGZvciB5ZWFyIGFuZCBtb250aC4KCmBgYHtyfQp2aXNpdHMuMiA9IG11dGF0ZSh2aXNpdHMuMSwKICAgICAgICAgICAgICAgICAgUmVwbGljYXRlcyA9IGFzX2ZhY3RvcihSZXBsaWNhdGVzKSwKICAgICAgICAgICAgICAgICAgIyBDb21iaW5lIHNpbWlsYXIgbWVzaCBzaXplcyB0byB0aGUgdGVudGggZGVjaW1hbAogICAgICAgICAgICAgICAgICBNZXNoU2l6ZSA9IGNhc2Vfd2hlbihNZXNoU2l6ZSA8IDQgfiAzLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lc2hTaXplID4gNCAmIE1lc2hTaXplIDwgNyB+IDYuNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzaFNpemUgPiA3ICYgTWVzaFNpemUgPCAxMSB+IDkuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzaFNpemUgPT0gMTIuNyB+IDEyLjcpICU+JQogICAgICAgICAgICAgICAgICAgIGFzLmZhY3RvcigpKSAlPiUKICAjIEFkZCB0ZW1wb3JhbCB2YXJpYWJsZXMKICBsZWZ0X2pvaW4oc2VsZWN0KHRpbWVzLCBWaXNpdElELCBZZWFyLCBNb250aCksIGJ5ID0gIlZpc2l0SUQiKQpgYGAKCmBgYHtyfQojIFNhbXBsZXMgYnkgTWVzaFNpemUgYW5kIFllYXIsCmZpbHRlcih2aXNpdHMuMiwgWWVhciA+IDE5ODkpICU+JQogIGdncGxvdChhZXMoeCA9IERhdGUsIHkgPSBNZXNoU2l6ZSwgY29sb3IgPSBNZXNoU2l6ZSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTMsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiV5IiwKICAgICAgICAgICAgICAgZGF0ZV9icmVha3MgPSAiMiB5ZWFycyIpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiTWVzaCBTaXplIChtbSkiLAogICAgICAgdGl0bGUgPSAiU2FtcGxlcyBieSBZZWFyIGFuZCBNZXNoIFNpemUiLAogICAgICAgc3VidGl0bGUgPSAiRXhjbHVkaW5nIDE5NzY7IG5vLiBzYW1wbGVzIGNlbnRlcmVkIG92ZXIgbWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKIyBTYW1wbGVzIGJ5IE1vbnRoIGFuZCBNZXNoU2l6ZSwKZmlsdGVyKHZpc2l0cy4yLCBZZWFyID4gMTk4OSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gTW9udGgsIHkgPSBNZXNoU2l6ZSwgY29sb3IgPSBNZXNoU2l6ZSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTMsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSAiTW9udGgiLCB5ID0gIk1lc2ggU2l6ZSAobW0pIiwKICAgICAgIHRpdGxlID0gIlNhbXBsZXMgYnkgTW9udGggYW5kIE1lc2ggU2l6ZSIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGNsdWRpbmcgMTk3Njsgbm8uIHNhbXBsZXMgbGFiZWxsZWQgYnkgbW9udGgiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgojIFNhbXBsZXMgYnkgUmVwbGljYXRlcyBhbmQgWWVhciwKZmlsdGVyKHZpc2l0cy4yLCBZZWFyID4gMTk4OSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGF0ZSwgeSA9IFJlcGxpY2F0ZXMsIGNvbG9yID0gUmVwbGljYXRlcykpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTEsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfbGFiZWxzID0gIiV5IiwKICAgICAgICAgICAgICAgZGF0ZV9icmVha3MgPSAiMiB5ZWFycyIpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiUmVwbGljYXRlcyIsCiAgICAgICB0aXRsZSA9ICJTYW1wbGVzIGJ5IFllYXIgYW5kIFJlcGxpY2F0ZXMiLAogICAgICAgc3VidGl0bGUgPSAiRXhjbHVkaW5nIDE5NzY7IG5vLiBzYW1wbGVzIGNlbnRlcmVkIG92ZXIgbWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKIyBTYW1wbGVzIGJ5IFJlcGxpY2F0ZXMgYW5kIE1vbnRoLApmaWx0ZXIodmlzaXRzLjIsIFllYXIgPiAxOTg5KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBNb250aCwgeSA9IFJlcGxpY2F0ZXMsIGNvbG9yID0gUmVwbGljYXRlcykpICsKICBnZW9tX2JveHBsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoc2l6ZSA9IDAuNSwgYWxwaGEgPSAwLjc1KSArCiAgc3RhdF9zdW1tYXJ5KGdlb20gPSAidGV4dCIsIHZqdXN0ID0gLTEsIGNvbG9yID0gImJsYWNrIiwKICAgICAgICAgICAgICAgZnVuLmRhdGEgPSBmdW5jdGlvbih4KSB7CiAgICAgICAgICAgICAgICAgcmV0dXJuKGMoeSA9IG1lZGlhbih4KSwgbGFiZWwgPSBsZW5ndGgoeCkpKQogICAgICAgICAgICAgICB9KSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTcGVjdHJhbCIpICsKICBsYWJzKHggPSAiTW9udGgiLCB5ID0gIlJlcGxpY2F0ZXMiLAogICAgICAgdGl0bGUgPSAiU2FtcGxlcyBieSBNb250aCBhbmQgUmVwbGljYXRlcyIsCiAgICAgICBzdWJ0aXRsZSA9ICJFeGNsdWRpbmcgMTk3Njsgbm8uIHNhbXBsZXMgbGFiZWxsZWQgYnkgbW9udGgiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoK